package org.btik.light.mobile.ui.serial.controller.console;

import com.hoho.android.usbserial.driver.UsbSerialPort;
import org.btik.light.mobile.ui.serial.controller.console.SerialConsole;

import java.io.IOException;
import java.util.LinkedList;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * @author lustre
 * @since 2023/4/9 17:01
 */
public class SerialConsoleThread extends Thread {

    public static final String SERIAL_CONSOLE_THREAD = "SerialConsoleThread";
    private volatile UsbSerialPort usbSerialPort;

    private SerialConsole serialConsole;

    private final LinkedList<StringBuilder> consoleLineQueue = new LinkedList<>();
    private final byte[] lock = new byte[0];


    private volatile boolean suspend = true;

    @Override
    public void run() {
        byte[] buffer = new byte[255];
        while (!Thread.interrupted()) {
            try {
                synchronized (lock) {
                    if (suspend || usbSerialPort == null || serialConsole == null || !usbSerialPort.isOpen()) {
                        lock.wait();
                    }
                    int len = usbSerialPort.read(buffer, 100);
                    if (len < 1) {
                        continue;
                    }
                    serialConsole.refreshUI(buffer, len);
                }


            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
                if (Thread.interrupted()) {
                    break;
                }
            }
        }
    }

    public void detachUsb() {
        synchronized (lock) {
            suspend = true;
            this.usbSerialPort = null;
            this.serialConsole = null;
        }
    }

    public void attachUsb(UsbSerialPort usbSerialPort, SerialConsole serialConsole) {
        synchronized (lock) {
            suspend = false;
            this.usbSerialPort = usbSerialPort;
            this.serialConsole = serialConsole;
            lock.notify();
        }
    }

    LinkedList<StringBuilder> getConsoleLineQueue() {
        return consoleLineQueue;
    }
}
